unit BubbleSortAnimation;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

const
  N = 10;
  w = 50;
  h = w;
  x0 = 0;
  y0 = 0;
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Button1: TButton;
    ScrollBar1: TScrollBar;
    Timer2: TTimer;
    ScrollBar2: TScrollBar;
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure ScrollBar1Change(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure ScrollBar2Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  arr: array of integer;
  i, j, a, k, runNumber, step, flag, t, s, V, c: integer;
  arr1 : array of TPanel;
  b:   TPanel;
implementation

{$R *.dfm}

procedure Draw;
begin
  for k:=0 to N-1 do
  begin
    arr1[k].Color:=clWhite;
  end;
  if (step=1) and (c=0) then
  begin
    arr1[0].Color:=clRed;
    arr1[1].Color:=clRed;
  end
  else
  begin
    arr1[step].Color:=clRed;
    if (step<=N-2-runNumber ) then
      arr1[step+1].Color:=clRed
    else
      arr1[step-1].Color:=clRed;
    arr1[step].Color:=clRed;
  end;
  for k:=0 to N-1 do
    arr1[k].Caption:=IntToStr(arr[k]);
  c:=1;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (runNumber<=N-2) and (t=1) then
  begin
    if (step<=N-2-runNumber) then
    begin
      if (arr[step]>arr[step+1]) then
      begin
        if (s=0) then
        begin
          Timer1.Enabled:=False;
          Timer2.Enabled:=True;
          exit;
        end;
        s:=0;
        a:=arr[step+1];
        arr[step+1]:=arr[step];
        arr[step]:=a;
        step:=step+1;
        Draw;
        Form1.Refresh;
        flag:=0;
      end
      else
      begin
        step:=step+1;
        Draw;
      end;
    end
    else
    begin
      if (flag=0) then
        t:=1
      else
        t:=0;
      runNumber:=runNumber+1;
      flag:=1;
      Form1.Refresh;
      step:=0;
      c:=0;
    end;
  end
  else
  begin
    Timer1.Enabled:=False;
    ShowMessage('Array has been sorted');
  end;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
  c:=1;
  s:=0;
  V:=5;
  setlength(arr1, N);
  t:=1;
  runNumber:=0;
  step:=0;
  setlength(arr, N);
  randomize;
  for i:=0 to N-1 do
    arr[i]:=random(N);
  for j:=0 to N-1 do
  begin
    arr1[j]:=TPanel.Create(Form1);
    arr1[j].Width := w;
    arr1[j].Height := h;
    arr1[j].Parent := Form1;
    arr1[j].Left := (w+10)*j;
  end;
  Draw;
  Timer1.Enabled:=True;
end;


procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
  Timer1.Interval:=(ScrollBar1.Max+1)-(ScrollBar1.Position);
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  arr1[step].Left:=arr1[step].Left+V;
  arr1[step+1].Left:=arr1[step+1].Left-V;
  if (arr1[step].Left>=(step+1)*(w+10)) then
  begin
    b:=arr1[step+1];
    arr1[step+1]:=arr1[step];
    arr1[step]:=b;
    s:=1;
    Timer1.Enabled:=True;
    Timer2.Enabled:=False;
  end;
end;

procedure TForm1.ScrollBar2Change(Sender: TObject);
begin
  Timer2.Interval:=(ScrollBar2.Max+1)-(ScrollBar2.Position);
end;

end.
